import {
  TEqualFunc,
  TCompareFunc,
  defaultCompare,
} from '../utils/tools';
import {
  TElements,
  LinkedNodeBase,
  LinkedListBase,
} from './base';
import { LESS_THAN, } from '../utils/constant';

export class SortedLinkedList extends LinkedListBase<LinkedNodeBase> {
  protected static compareFunc: TCompareFunc;

  public constructor(
    elements?: TElements,
    equalFunc?: TEqualFunc,
    compareFunc?: TCompareFunc
  ) {
    SortedLinkedList.compareFunc = compareFunc || defaultCompare;

    const initSortElems = (pre, next) => {
      return SortedLinkedList.compareFunc(pre, next);
    };

    super(LinkedNodeBase, elements?.sort(initSortElems), equalFunc);
  }

  public insert(element: any) {
    let indexSort: number;

    if (this.isEmpty()) {
      indexSort = 0;  
    } else {
      indexSort = this.getElemInsertPos(element);
    }

    return !!super.insert(element, indexSort);
  }

  protected getElemInsertPos(element) {
    const size = this.size();
    let current: TTNulish<LinkedNodeBase> = this.head;
    let i = 0;

    for (; i < size; i++) {
      const comp = SortedLinkedList.compareFunc(element, current?.value);
      
      if (comp === LESS_THAN) {
        return i;
      } else {
        current = current?.next;
      }
    }
    return i;
  }
}
